package com.zzyl.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.AlertRuleDto;
import com.zzyl.entity.AlertRule;
import com.zzyl.entity.Device;
import com.zzyl.entity.DeviceData;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.AlertRuleMapper;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.AlertRuleVo;
import com.zzyl.vo.DeviceDataVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;


@Slf4j
@Component
public class AutoAlertTask {

    @Autowired
    private AlertRuleMapper alertRuleMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private DeviceMapper deviceMapper;

    @Scheduled(cron = "0 */1 * * * ?")
    public void starAutoAlertTask() {
        log.info("开始执行任务，当前时间：{}", LocalDateTime.now());

        // 1. 查询所有规则（安全判断）
        List<AlertRuleVo> ruleList = alertRuleMapper.selectAll();
        if (CollectionUtils.isEmpty(ruleList)) {
            log.warn("未找到任何告警规则，跳过本次任务");
            return;
        }

        // 2. 获取所有设备的 iotId
        Set<String> allIotIds = new HashSet<>();
        for (AlertRuleVo rule : ruleList) {
            List<String> iotIds = deviceMapper.selectIotIdByProductKey(rule.getProductKey());
            if (CollectionUtils.isNotEmpty(iotIds)) {
                allIotIds.addAll(iotIds);
            }
        }

        if (CollectionUtils.isEmpty(allIotIds)) {
            log.warn("未找到任何设备，跳过本次任务");
            return;
        }

        // 3. 从 Redis 获取所有设备的最新数据（按 functionId 分组）
        Map<String, DeviceDataVo> functionIdToLatestData = new HashMap<>();
        for (String iotId : allIotIds) {
            // 获取该 iotId 的数据（ Redis 中存储结构为：
            // key: CacheConstants.DEVICE_LASTDATA_CACHE_KEY
            // field: iotId
            // value: JSON 字符串（包含该 iotId 的所有物模型数据）
            Object redisData = redisTemplate.opsForHash().get(
                    CacheConstants.DEVICE_LASTDATA_CACHE_KEY,
                    iotId
            );

            if (redisData == null){ continue;}

            // 解析 JSON 字符串为 List<DeviceDataVo>
            List<DeviceDataVo> deviceDataList;
            if (redisData instanceof String) {
                deviceDataList = JSON.parseArray((String) redisData, DeviceDataVo.class);
            } else if (redisData instanceof List) {
                deviceDataList = (List<DeviceDataVo>) redisData;
            } else {
                log.warn("iotId={} 的数据格式不支持", iotId);
                continue;
            }

            // 4. 对每个 iotId 的数据，按 functionId 分组取最新
            for (DeviceDataVo data : deviceDataList) {
                if (StringUtils.isEmpty(data.getFunctionId()) || data.getCreateTime() == null) {
                    continue;
                }
                // 比较并更新全局最新数据
                DeviceDataVo currentLatest = functionIdToLatestData.get(data.getFunctionId());
                if (currentLatest == null || data.getCreateTime().isAfter(currentLatest.getCreateTime())) {
                    functionIdToLatestData.put(data.getFunctionId(), data);
                }
            }
        }

        // 5. 判断最新的数据是否存在符合规则的数据
        for (AlertRuleVo rule : ruleList) {
            DeviceDataVo latestData = functionIdToLatestData.get(rule.getFunctionId());
            if (latestData == null) {
                log.debug("functionId={} 无最新数据，跳过规则校验", rule.getFunctionId());
                continue;
            }

            //执行规则校验逻辑
            // 例如：rule.check(latestData);
            log.info("规则校验中: functionId={}, dataValue={}",
                    rule.getFunctionId(),
                    latestData.getDataValue()
            );
        }















        log.info("任务执行完成，共处理 {} 个 functionId", functionIdToLatestData.size());
    }
}